package org.redmagic.client.web;

import java.net.URI;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.redmagic.api.RedMagicRequest;
import org.redmagic.api.RedMagicResponse;
import org.redmagic.api.RedMagicResponseFactory;
import org.redmagic.client.api.RedMagicTransaction;
import org.springframework.stereotype.Component;

// Execute a single transaction
@Component
public class RedMagicHttpTransaction implements RedMagicTransaction {

	private static final Log LOG = LogFactory.getLog(RedMagicHttpTransaction.class);
	
	private HttpClient httpClient;
	
	private RedMagicResponseFactory responseFactory;
	
	public RedMagicHttpTransaction(RedMagicResponseFactory responseFactory) {
		this.httpClient = new DefaultHttpClient();
		this.responseFactory = responseFactory;
	}
	
	@Override
	public RedMagicResponse execute(URI uri, RedMagicRequest request, String requestMediaType) {
		
		String response = null;
		
		try {
			// Setup the request
			HttpPost post = new HttpPost(uri);
			post.addHeader("Accept", responseFactory.getMediaType());
			post.addHeader("Content-Type", requestMediaType);
			post.setEntity(new StringEntity(request.marshall()));
			
			// Execute the request
			HttpResponse httpResponse = httpClient.execute(post);
			
			// Handle the response
			response = EntityUtils.toString(httpResponse.getEntity());
			int statusCode = httpResponse.getStatusLine().getStatusCode();
			if (statusCode >= 200 && statusCode < 300) {
				LOG.info("Success: " + response);
			} else {
				LOG.warn("Failure (" + statusCode + "): " + httpResponse.getStatusLine().getReasonPhrase());
			}
			
		} catch (Exception e) {
			LOG.error("Error during transaction! ", e);
		}

		// Shutdown the connection
		if (httpClient != null) {
			ClientConnectionManager ccm = httpClient.getConnectionManager();
			if (ccm != null) {
				ccm.shutdown();
			}
		}
		
		return responseFactory.createResponse(response);
	}
	
}
